#ifndef __LIB_AGORA_ADMIN_DATABASE_H__
#define __LIB_AGORA_ADMIN_DATABASE_H__

#include <string>
#include <vector>
#include <map>
#include "IDatabase.h"
#include "IDbValue.h"
#include "sqlite3.h"

class	Database : public IDatabase
{
public:
	//typedef std::vector<std::map<std::string, IDbValue*>*>	DbResult;

	//static Database*	GetDatabase(void);
	Database();
	const unsigned int	Open(const std::string& dbPath);
	const unsigned int	Close();

	// UserManager db functions
	DbResult*			SelectAllUser();
	DbResult*			SelectUser(const unsigned int id);
	DbResult*			SelectUser(const std::string& login);
	void				UpdateUser(const unsigned int id, const std::string& login, const std::string& password);
	const unsigned int	CreateUser(const std::string& login, const std::string& password);
	void				DeleteAllUser();
	void				DeleteUser(const unsigned int id);
	//// User db funtions
	const unsigned int	SelectUserId(const std::string& login);
	std::string			SelectUserLogin(const unsigned int id);
	void				UpdateUserLogin(const unsigned int id, const std::string& login);
	std::string			SelectUserPassword(const unsigned int id);
	void				UpdateUserPassword(const unsigned int id, const std::string& password);
	//// ChannelManager db functions
	DbResult*			SelectAllChannel();
	DbResult*			SelectChannel(const unsigned int idParent, const std::string& name);
	//void				UpdateAllChannel();
	//void				UpdateChannel(const unsigned int id);
	const unsigned int	CreateChannel(const unsigned int idParent, const std::string& name, const unsigned int maxNameLenght, const std::string& password, const unsigned int maxPasswordLenght, const std::string& motd, const unsigned int maxMotdLenght, const std::string& description, const unsigned int maxDescriptionLenght, const bool visible, const unsigned int maxUser, const unsigned int maxTalker);
	void				DeleteAllChannel();
	void				DeleteChannel(const unsigned int id);
	//// Channel db functions
	const unsigned int	SelectChannelId(const unsigned int idParent, const std::string& name);
	const unsigned int	SelectChannelIdParent(const unsigned int id);
	void				UpdateChannelIdParent(const unsigned int id, const unsigned int idParent);
	const std::string&	SelectChannelName(const unsigned int id);
	void				UpdateChannelName(const unsigned int id, const std::string& name);
	const unsigned int	SelectChannelMaxNameLenght(const unsigned int id);
	void				UpdateChannelMaxNameLenght(const unsigned int id, const unsigned int maxNameLenght);
	const std::string&	SelectChannelPassword(const unsigned int id);
	void				UpdateChannelPassword(const unsigned int id, const std::string& password);
	const unsigned int	SelectChannelMaxPasswordLenght(const unsigned int id);
	void				UpdateChannelMaxPasswordLenght(const unsigned int id, const unsigned int maxPasswordLenght);
	const std::string&	SelectChannelMotd(const unsigned int id);
	void				UpdateChannelMotd(const unsigned int id, const std::string& motd);
	const unsigned int	SelectChannelMaxMotdLenght(const unsigned int id);
	void				UpdateChannelMaxMotdLenght(const unsigned int id, const unsigned int maxMotdLenght);
	const std::string&	SelectChannelDescription(const unsigned int id);
	void				UpdateChannelDescription(const unsigned int id, const std::string& description);
	const unsigned int	SelectChannelMaxDesciptionLenght(const unsigned int id);
	void				UpdateChannelMaxDesciptionLenght(const unsigned int id, const unsigned int maxDescriptionLenght);
	const bool			SelectChannelVisibility(const unsigned int id);
	void				UpdateChannelVisibility(const unsigned int id, const bool visible);
	const unsigned int	SelectChannelMaxUser(const unsigned int id);
	void				UpdateChannelMaxUser(const unsigned int id, const unsigned int maxUser);
	const unsigned int	SelectChannelMaxTalker(const unsigned int id);
	void				UpdateChannelMaxTalker(const unsigned int id, const unsigned int maxTalker);
	//// Right db functions
	DbResult*			SelectChannelRight(const unsigned int id);
	DbResult*			SelectChannelRight(const unsigned int idUser, const unsigned int idChannel);
	const unsigned int	SelectChannelRightId(const unsigned int idUser, const unsigned int idChannel);
	const unsigned int	CreateChannelRightDefault(const unsigned int idUser, const unsigned int idChannel);
	void				UpdateChannelRight(const unsigned int id, const bool canCreate, const bool canDelete, const bool canEdit, const bool canEditUser, const bool canTalk, const bool canWrite, const bool canKick, const bool canBan);
	void				UpdateChannelRightCanCreateChild(const unsigned int id, const bool value);
	void				UpdateChannelRightCanDeleteChild(const unsigned int id, const bool value);
	void				UpdateChannelRightCanEdit(const unsigned int id, const bool value);
	void				UpdateChannelRightCanEditUserRight(const unsigned int id, const bool value);
	void				UpdateChannelRightCanTalk(const unsigned int id, const bool value);
	void				UpdateChannelRightCanWrite(const unsigned int id, const bool value);
	void				UpdateChannelRightCanKick(const unsigned int id, const bool value);
	void				UpdateChannelRightCanBan(const unsigned int id, const bool value);
	//// Server db functions
	const std::string&	SelectServerName();
	void				UpdateServerName(const std::string& name);
	DbResult*			SelectServerBanListLogin();
	void				InsertServerBanListLogin(const std::string& login);
	void				DeleteServerBanListLogin(const std::string& login);
private:
	const unsigned int	Execute(const std::string& statement, DbResult* result);
	const unsigned int	Execute(const std::string& statement);
private:
	//Database();
	//static Database*	_instance;
	sqlite3*			_db;
};

#endif